package cn.wolfcode.car.exception;

import cn.wolfcode.car.domain.Employee;
import cn.wolfcode.car.domain.Log;
import cn.wolfcode.car.service.ILogService;
import com.alibaba.fastjson.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

@Component //把当前类注入到spring容器中
@Aspect    //把当前类标识为一个切面供容器读取
public class AopConfig {

    @Autowired
    private ILogService logService;

    private Log log = new Log();

    /**
     * 指定切入点
     * 对贴有自定义注解@RequiredPermission的方法，进行切面
     */
    @Pointcut("@annotation(org.apache.shiro.authz.annotation.RequiresPermissions)")
    private void useMethod() {
    }

    /**
     * 对切入点进行增强
     */
    @Around(value = "useMethod()")
    public Object recordLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //执行处理方法（执行控制器中的方法）

        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getResponse();

        //开始时间
        long startTime = System.currentTimeMillis();

        //获取登录人信息
        Subject subject = SecurityUtils.getSubject();
        Employee employee = (Employee) subject.getPrincipal();
        Object result = null;

        if (employee != null) {
            //用户名
            System.out.println("username=" + employee.getUsername());
            log.setUsername(employee.getUsername());
            //用户操作

            //请求方法
            System.out.println("uri=" + request.getRequestURI());
            log.setReqAction(request.getRequestURI());
            //请求参数
            Map map = request.getParameterMap();
            JSONObject jsonObj = new JSONObject(map);
            System.out.println("mapJson============" + jsonObj.toString());
            log.setReqParam(jsonObj.toString());
            //请求时间
            long endTime = System.currentTimeMillis();
            System.out.println("start===" + startTime);
            System.out.println("end===" + endTime);
            long req_time = endTime - startTime;
            log.setReqTime((int) req_time);
            //创建时间
            log.setCreateTime(new Date());
            //ip
            String ip = request.getRemoteAddr();
            log.setReqIp(ip);
            //取操作名
            //获取类的字节码对象，通过字节码对象获取方法信息
            //获取用户操作
            Class<?> targetCls = proceedingJoinPoint.getTarget().getClass();
            //获取方法签名(通过此签名获取目标方法信息)
            MethodSignature ms = (MethodSignature) proceedingJoinPoint.getSignature();
            //获取目标方法上的注解指定的操作名称
            Method targetMethod =
                    targetCls.getDeclaredMethod(
                            ms.getName(),
                            ms.getParameterTypes());
            RequiresPermissions anno = targetMethod.getAnnotation(RequiresPermissions.class);
            String[] operation = anno.value();
            log.setReqDo(operation[1]);


            try {
                result = proceedingJoinPoint.proceed();
                log.setReqRes("成功");
                log.setErrorMessage("无");
            } catch (Exception e) {
                log.setReqRes("失败");
                log.setErrorMessage(e.getMessage());
            } finally {
                logService.save(log);
            }
            System.out.println(log);
        }


        //result是方法的返回值，直接return回去就会返回给springmvc处理
        return result;
    }


}